﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.IO;

namespace MulticastTV
{

    /// <summary>
    /// Import from AditeyaTV(atvlist), m3u, csv or excel(xls) file format
    /// Here you can add import functions for other formats !!!
    /// Output datatable has to be in AditeyatTV format
    /// </summary>
    public static class Import
    {
        static char[] delimiterChars1 = { ';' };
        static char[] delimiterChars2 = { ',' };
        static char[] delimiterChars3 = { ':' };
        static char[] delimiterChars4 = { '-' };
        static char[] delimiterChars5 = { '@' };

        /// <summary>
        /// Returns TEMPORARY DataTable!!! One channel can have MULTIPLE ip numbers - look aditeyaTV format.
        /// </summary>
        /// <param name="path">Startup path</param>
        /// <param name="clean">Common aplication folder</param>
        /// <param name="clean">File to import from</param>
        public static DataTable array(string path, string appath, string file, ref bool NeedsAdditionalInfo)
        {

            DataTable dt = new DataTable();

            dt.Columns.Add("Channel", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Group", typeof(string));  // Multiple groups must be separated by a comma.
            dt.Columns.Add("Locked", typeof(string)); // "0" or "1"
            dt.Columns.Add("Ip", typeof(string[]));   // language+ip:port example: [english+239.255.0.108:5002,chezch+239.255.0.179:5002]

            // Optional EpgID column
            DataColumn column;
            column = new DataColumn();
            column.DataType = typeof(string);
            column.ColumnName = "EpgId";
            column.ReadOnly = false;
            column.Unique = false;
            column.DefaultValue = "";
            dt.Columns.Add(column);

            string ext = Path.GetExtension(file).ToUpper();

            if (ext == ".XLS")
            {
                NeedsAdditionalInfo = false;
                ImportFromExcel exc = new ImportFromExcel(file);
                dt = exc.ConvertToDatatable(dt, true);
            }

            else if (ext == ".CSV")
            {
                NeedsAdditionalInfo = false;
                ImportFromExcel exc = new ImportFromExcel(file);
                dt = exc.fromCsv(file, dt);
            }

            else if (ext == ".ATVLIST")
            {
                NeedsAdditionalInfo = false;
                FillDtFromAditeyaTVFormat(file, dt);
            }

            else if (ext == ".M3U")
            {
                NeedsAdditionalInfo = true;
                FillDtFromM3u(file, dt, ref NeedsAdditionalInfo);
            }

            return dt;
        }

        static void FillDtFromAditeyaTVFormat(string file, DataTable dt)
        {
            string line;
            StreamReader SR = File.OpenText(file);
            line = SR.ReadLine();
            while (line != null)
            {
                if (line.Length > 28)
                {
                    int channel = int.Parse(line.Split(delimiterChars1)[0].Substring(8));
                    string name = line.Split(delimiterChars1)[1].Substring(5);
                    string locked = line.Split(delimiterChars1)[2].Substring(7);
                    string group = line.Split(delimiterChars1)[3].Substring(6);
                    string audiotemp = line.Split(delimiterChars1)[4].Substring(6);
                    string[] audio = audiotemp.Split(delimiterChars2);
                    dt.Rows.Add(channel, name, group, locked, audio);
                }
                line = SR.ReadLine();
            }
            SR.Close();
        }


        // Standard and Tano m3u
        static void FillDtFromM3u(string file, DataTable dt, ref bool NeedsAdditionalInfo)
        {
            bool chanfromartist = false;
            string line;
            int i = 1;
            int lastchan = 0;
            int mchannel = 0;
            string mname = "";
            string mlocked = "0";
            string mgroups = "";
            string language = "";
            string epgid = "";
            int counter = 0;

            StreamReader SR = File.OpenText(file);
            line = SR.ReadLine();

            if (line.StartsWith("#EXTM3U"))
                line = SR.ReadLine();
            else
                return; //Not a m3u file

            while (line != null)
            {
                if (line.Length == 0)
                {
                    line = SR.ReadLine();
                    continue;
                }

                string options = "";
                if (line.StartsWith("#") && line.Contains(":"))
                    options = line.Split(":".ToCharArray())[0];

                switch (options)
                {
                    case "#EXTINF":

                        //m3u name and number
                        mchannel = lastchan + 1;
                        int parsed = 0;
                        mname = line.Substring(line.IndexOf(",") + 1);

                        // check for format of first entry
                        if (counter == 0 && mname.Contains("-") && int.TryParse((mname.Split(delimiterChars4, 2)[0].Trim()), out parsed))
                            chanfromartist = true;

                        if (chanfromartist)
                        {
                            //Try to get channel number from artist name. 
                            if (int.TryParse((mname.Split(delimiterChars4, 2)[0].Trim()), out parsed))
                            {
                                mname = mname.Split(delimiterChars4, 2)[1];
                                mchannel = parsed;
                            }
                            else
                                chanfromartist = false;
                        }
                        else
                        {
                            // Try to get channel number from length field.
                            int start = line.IndexOf(":") + 1;
                            int stop = line.IndexOf(",");
                            int itchan = 0;
                            string tchan = line.Substring(start, stop - start);
                            if (int.TryParse(tchan, out itchan))
                            {
                                if (itchan != 0)
                                    mchannel = itchan;
                            }
                        }
                        mname = mname.Trim();

                        counter += 1;
                        break;

                    case "#EXTTV":

                        if (NeedsAdditionalInfo == true)
                            NeedsAdditionalInfo = false; // Tano format has all necessary data

                        // Extended Tano format
                        string[] data = line.Split(":".ToCharArray())[1].Split(";".ToCharArray());
                        mgroups = data[0];
                        language = data[1];
                        epgid = data[2];
                        break;

                    case "":
                        bool ip_start_found = false;

                        // Find multicast type of an address.
                        int find = line.LastIndexOf("//@");
                        if (find != -1)
                        {
                            ip_start_found = true;
                            find += 3;
                        }
                        else
                        {
                            find = line.LastIndexOf("//");
                            if (find != -1)
                            {
                                find += 2;
                                // Check for NIC address prefix, separated with "@".
                                int nicseparator = line.IndexOf("@", Math.Max(0, find));
                                if (nicseparator != -1)
                                {
                                    find = nicseparator + 1;
                                }
                                else
                                {
                                    // Check for some other type of prefixes.
                                    int pf_http = line.IndexOf("/http/", find);
                                    int pf_udp = line.IndexOf("/udp/", find);
                                    if (pf_http != -1)
                                        find = pf_http + 6;
                                    else if (pf_udp != -1)
                                        find = pf_udp + 5;
                                }
                                ip_start_found = true;
                            }
                        }

                        if (ip_start_found)
                        {
                            line = line.Substring(find);
                            line = "+" + line;
                            line = language + line;
                            dt.Rows.Add(mchannel, mname, mgroups, mlocked, new string[] { line }, epgid);
                            lastchan = mchannel;
                            i++;
                            //reset
                            mname = "";
                            mlocked = "0";
                            mgroups = "";
                            epgid = "";
                        }


                        break;
                }
                line = SR.ReadLine();
            }
            SR.Close();
        }
    }
}
